package cn.hutool.core.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;


/**
 * itree util impl
 *
 * @author bai
 * @date 2023/02/20
 */
public class TreeUtils<E>  {

	private final List<E> boList;

	private Function<E, Boolean> RootNodeFunc;

	private IsParent<E> NodeFunc;

	public TreeUtils(final List<E> boList) {
		this.boList = boList;
	}

	public void setRootNodeFunc(Function<E, Boolean> rootNodeFunc) {
		this.RootNodeFunc = rootNodeFunc;
	}

	public void setNodeFunc(IsParent<E> nodeFunc) {
		this.NodeFunc = nodeFunc;
	}

	@FunctionalInterface
	public interface IsParent<E> {

		Boolean access(E e, E parent);
	}

	@FunctionalInterface
	public interface Customer<E> {

		void access(E e, List<E> list);
	}


	/**
	 * 获取根节点的列表
	 *
	 * @param function 函数
	 * @return {@link List}<{@link E}>
	 */
	private List<E> getRootNode(final Function<E, Boolean> function) {
		final List<E> rootMenuLists = new ArrayList<>();
		for (E menuNode : boList) {
			if (function.apply(menuNode)){
				rootMenuLists.add(menuNode);
			}
		}
		return rootMenuLists;
	}

	/**
	 * 建立树形结构
	 *
	 * @param consumer 消费者
	 * @return List<E>
	 */
	public List<E> buildTree(final Customer<E> consumer) {
		final List<E> treeMenus = new ArrayList<>();
		for (E e : getRootNode(RootNodeFunc)) {
			treeMenus.add(buildChildrenTree(e, consumer, NodeFunc));
		}
		return treeMenus;
	}

	/**
	 * 递归，建立子树形结构
	 *
	 * @param pNode    p节点
	 * @param consumer 消费者
	 * @param function 函数
	 * @return E
	 */
	private E buildChildrenTree(final E pNode, final Customer<E> consumer, final IsParent<E> function) {
		final List<E> childrenMenus = new ArrayList<E>();
		for (E e : boList) {
			if (function.access(pNode,e)) {
				childrenMenus.add(buildChildrenTree(e,consumer,function));
			}
		}
		consumer.access(pNode, childrenMenus);
		return pNode;
	}
}
